﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Forms;

namespace read2imu
{
    public partial class mainForm : Form
    {
        UltraHighAccurateTimer mainTimer = new UltraHighAccurateTimer();
        UltraHighAccurateTimer updateTimer = new UltraHighAccurateTimer();
        public static float[] A1 = new float[3], G1 = new float[3], H1 = new float[3], angle1 = new float[3];
        public static float[] A2 = new float[3], G2 = new float[3], H2 = new float[3], angle2 = new float[3];
        public static int[] distace = new int[3];
        public static float[] _A1 = new float[3], _A2 = new float[3];//代表重力在三个轴的分量
        public static float[] bias1 = { -0.009f, 0.007f, 0.010f }, bias2 = { -0.007f, 0.012f, 0.008f };
        public static float[] v1 = new float[3], v2 = new float[3];//代表积分的速度
        public static float[] x1 = new float[3], x2 = new float[3];//代表积分的位移
        //加速度，角速度，磁场，角度
        TextBox[] textBox_angle1 = new TextBox[3];
        TextBox[] textBox_angle2 = new TextBox[3];
        TextBox[] textBox_A1 = new TextBox[3];
        TextBox[] textBox_A2 = new TextBox[3];
        TextBox[] textBox_distance = new TextBox[3];
        TextBox[] textBox_A1_ = new TextBox[3];//重力在三个角度下的分量
        TextBox[] textBox_A2_ = new TextBox[3];
        public static DataTable dataGridView_data;
        public mainForm()
        {
            InitializeComponent();
        }

        private void mainForm_Load(object sender, EventArgs e)
        {
            //CheckForIllegalCrossThreadCalls = false;
            //MainTimer.Elapsed += new System.Timers.ElapsedEventHandler(sss);
            //MainTimer.AutoReset = true;
            //MainTimer.Interval = 1000 + 0.5;//0.01*1000+0.5                                
            //MainTimer.Enabled = true;//定时器使能
            mainTimer.Interval = 50;  //定时间隔50ms
            mainTimer.Tick += new UltraHighAccurateTimer.ManualTimerEventHandler(mainTimer_Tick);
            updateTimer.Interval = 50;  //定时间隔50ms
            updateTimer.Tick += new UltraHighAccurateTimer.ManualTimerEventHandler(update);

            textBox_angle1[0] = textBox_ROW1;
            textBox_angle1[1] = textBox_PITCH1;
            textBox_angle1[2] = textBox_YAW1;
            textBox_angle2[0] = textBox_ROW2;
            textBox_angle2[1] = textBox_PITCH2;
            textBox_angle2[2] = textBox_YAW2;
            textBox_A1[0] = textBox_AX1;
            textBox_A1[1] = textBox_AY1;
            textBox_A1[2] = textBox_AZ1;
            textBox_A2[0] = textBox_AX2;
            textBox_A2[1] = textBox_AY2;
            textBox_A2[2] = textBox_AZ2;
            textBox_distance[0] = textBox_distance1;
            textBox_distance[1] = textBox_distance2;
            textBox_distance[2] = textBox_distance3;
            textBox_A1_[0] = textBox_Ax1_;
            textBox_A1_[1] = textBox_Ay1_;
            textBox_A1_[2] = textBox_Az1_;
            textBox_A2_[0] = textBox_Ax2_;
            textBox_A2_[1] = textBox_Ay2_;
            textBox_A2_[2] = textBox_Az2_;
            dataGridView_update_data();
            DateTime datetime = DateTime.Now;
            //MessageBox.Show((datetime.Ticks / 10000000d).ToString());
        }

        private void mainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            Environment.Exit(0);
        }

        private void comboBox_serialport_SelectedIndexChanged(object sender, EventArgs e)
        {
            serialPort.PortName = comboBox_serialport.Text;
        }

        private void comboBox_serialport_Click(object sender, EventArgs e)
        {
            comboBox_serialport.Items.Clear();
            comboBox_Port_Update();
        }

        private void comboBox_Port_Update()
        {
            comboBox_serialport.Items.Clear();
            RegistryKey keyCom = Registry.LocalMachine.OpenSubKey("Hardware\\DeviceMap\\SerialComm");
            if (keyCom != null)
            {
                string[] sSubKeys = keyCom.GetValueNames();
                foreach (string sName in sSubKeys)
                {
                    string sValue = (string)keyCom.GetValue(sName);
                    comboBox_serialport.Items.Add(sValue);
                }
            }
        }

        private void system_startup_Click(object sender, EventArgs e)
        {
            if (!serialPort.IsOpen)
            {
                if (comboBox_serialport.Text != "")
                    try
                    {
                        serialPort.Open();
                    }
                    catch
                    {
                        MessageBox.Show("串口" + serialPort.PortName + "打开失败！");
                        return;
                    }
                else
                {
                    MessageBox.Show("请选择串口");
                    return;
                }
            }
            else
            {
                MessageBox.Show("串口已打开，请检查串口占用");
                return;
            }

            comboBox_serialport.Enabled = false;
            system_startup.Enabled = false;
            button_serialclose.Enabled = true;
            MessageBox.Show("启动成功");
            Task.Factory.StartNew(new Action(() =>
            {
                receivemsg();   //循环接收函数
            }));
        }

        private void receivemsg()
        {
            int receive_length = 0;
            byte[] receive_data = new byte[6000];
            while (true)
            {
                try
                {
                    //Console.Write("aaa");
                    int receive_buffer_size = serialPort.BytesToRead > receive_data.Length ? receive_data.Length : serialPort.BytesToRead;
                    receive_length = serialPort.Read(receive_data, 0, receive_buffer_size);//读取的字节数
                    //Thread.Sleep(5);//延迟5ms
                    //Console.Write(receive_length + "\r\n");
                    data.data_decode(receive_length, receive_data);////调用数据解析函数

                    for (int k = 0; k < receive_length; k++)
                        richTextBox_receive.AppendText(receive_data[k].ToString("X2") + " ");
                    if (receive_length != 0)
                    {
                        dataGridView_update_data();//更新表格数据
                        richTextBox_receive.AppendText("\r\n");
                    }
                        
                    //Thread.Sleep(5);//延迟5ms

                    receive_data.Initialize();//初始化接收数据
                    receive_length = 0;//初始化字节长度

                    //update();
                    
                }
                catch (Exception ex)
                {
                    Console.Write("ERROR:"+ ex + "\r\n");
                }
            }
        }

        private void update(object sender)
        {
            //textBox_A1.Text = A[0].ToString();
            for (int k = 0; k < 3; k++)
            {
                textBox_angle1[k].Text = angle1[k].ToString("F3");
                textBox_angle2[k].Text = angle2[k].ToString("F3");
                textBox_A1[k].Text = A1[k].ToString("F3");
                textBox_A2[k].Text = A2[k].ToString("F3");
                if(Math.Abs(A1[k] - _A1[k]) > 0.015)
                {
                    v1[k] += updateTimer.Interval / 1000f * (A1[k] - _A1[k]);
                    x1[k] += updateTimer.Interval / 2000f * v1[k];
                }
                if (Math.Abs(A1[k] - _A1[k]) > 0.015)
                {
                    v2[k] += updateTimer.Interval / 1000f * (A2[k] - _A2[k]);
                    x2[k] += updateTimer.Interval / 2000f * v2[k];
                }                
                textBox_A1_[k].Text = v1[k].ToString("F3");
                textBox_A2_[k].Text = v2[k].ToString("F3");
                textBox_distance[k].Text = distace[k].ToString();
            }
        }

        private void button_serialclose_Click(object sender, EventArgs e)
        {
            comboBox_serialport.Enabled = true;
            system_startup.Enabled = true;
            serialPort.Close();
        }

        /// <summary>
        /// 提取datatable类型的数据
        /// </summary>
        public DataTable getdgvtotable(DataGridView dgv)
        {
            DataTable dt = new DataTable();
            for (int count = 0; count < dgv.Columns.Count; count++)
            {
                DataColumn dc = new DataColumn(dgv.Columns[count].Name.ToString());
                dt.Columns.Add(dc);
            }
            for (int count = 0; count < dgv.Rows.Count; count++)
            {
                DataRow dr = dt.NewRow();
                for (int countsub = 0; countsub < dgv.Columns.Count; countsub++)
                {
                    dr[countsub] = Convert.ToString(dgv.Rows[count].Cells[countsub].Value);
                }
                dt.Rows.Add(dr);
            }
            return dt;
        }

        private void button_savedata_Click(object sender, EventArgs e)
        {
            dataGridView_data = getdgvtotable(dataGridView);
            data.save_data_dialog();
            //dataForm data_form = new dataForm();   //新建一个实例
            //data_form.ShowDialog();    //打开新建的实例
        }

        private void button_clear_Click(object sender, EventArgs e)
        {
            if ((Button)sender == button_clear1)
                richTextBox_send.Clear();
            else if ((Button)sender == button_clear2)
                richTextBox_receive.Clear();
        }

        private void button_save_Click(object sender, EventArgs e)
        {
            data.save_data_dialog((Button)sender == button_save1 ?
                richTextBox_send : richTextBox_receive);
        }

        private void button_set_Click(object sender, EventArgs e)
        {
            mainTimer.Start();
            updateTimer.Start();
            button_set.Enabled = false;
            button_stop.Enabled = true;
        }

        private void button_stop_Click(object sender, EventArgs e)
        {
            mainTimer.Stop();
            updateTimer.Stop();
            button_set.Enabled = true;
            button_stop.Enabled = false;
        }

        bool temp = false;
        private void mainTimer_Tick(object sender)
        {
            if(temp == false)
            {
                byte[] cmd = data.read_cmd_generate(0x01, 0x3D, 6);//角度指令
                serialPort.Write(cmd, 0, cmd.Length);

                for (int k = 0; k < cmd.Length; k++)
                    richTextBox_send.AppendText(cmd[k].ToString("X2") + " ");
                if (cmd.Length != 0)
                    richTextBox_send.AppendText("\r\n");

                cmd = data.read_cmd_generate(0x01, 0x34, 3);//加速度指令
                serialPort.Write(cmd, 0, cmd.Length);

                for (int k = 0; k < cmd.Length; k++)
                    richTextBox_send.AppendText(cmd[k].ToString("X2") + " ");
                if (cmd.Length != 0)
                    richTextBox_send.AppendText("\r\n");

                temp = true;
                return;
            }
            if(temp == true)
            {
                byte[] cmd = data.read_cmd_generate(0x02, 0x34, 12);
                serialPort.Write(cmd, 0, cmd.Length);

                for (int k = 0; k < cmd.Length; k++)
                    richTextBox_send.AppendText(cmd[k].ToString("X2") + " ");
                if (cmd.Length != 0)
                    richTextBox_send.AppendText("\r\n");

                temp = false;
                return;
            }

        }

        public static string yyyyMMddhh;
        private void dataGridView_update_data()
        {
            dataGridView.SuspendLayout();
            int index = dataGridView.Rows.Add();
            yyyyMMddhh = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
            dataGridView.Rows[index].Cells[0].Value = yyyyMMddhh;
            for (int k = 0; k < 3; k++)
            {
                dataGridView.Rows[index].Cells[k + 1].Value = angle1[k];
                dataGridView.Rows[index].Cells[k + 4].Value = angle2[k];
            }

            dataGridView.ResumeLayout();
        }
    }
}
